# ConnectionServer - SocketServer that listens incoming connections.
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import socket
import logging
import threading

# Messaging system
from message_bus import MessageBus
from message_type_priority import MessageType, MessagePriority

from client_connection import ClientConnection

class ConnectionServer(threading.Thread):
    """
    Connection server listens incoming connections.
    
    On incoming connection ConnectionServer spawns a new ClientConnection thread
    that handels connection. This thread is registered to the MessageBus. This
    way backend can handle multiple connections simultaneously.
    """
      
    def __init__(self, logger, port, message_bus):
        """
        Creates a new ConnectionServer object
        @param logger: Logger object
        @param port: Port number for this server
        @param message_bus: Bind connecting client to this MessageBus object
        """
        threading.Thread.__init__(self)
        self.message_bus = message_bus # Message bus
        self.logger = logger # Logger object
        self.active = False # Is ConnectionServer active (listening incoming connections)
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Server socket
        self.server_socket.bind(('localhost', port))
        self.server_socket.listen(2)
        
    # Overrides method from Thread class
    def run(self):
        """Execute a new thread of control. Starts listening connections."""
        self.active = True
        self.logger.debug("ConnectionServer waiting incoming connections")
        while self.active:
            client_socket, address = self.server_socket.accept()
            self.logger.debug("Incoming connection accepted")
            client_connection = ClientConnection(client_socket, self.message_bus, self.logger)
            client_connection.start()